package com.bytz.modules.cms.order.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bytz.modules.cms.order.constant.OrderConstants;
import com.bytz.modules.cms.order.entity.Order;
import com.bytz.modules.cms.order.entity.OrderItem;
import com.bytz.modules.cms.order.mapper.OrderMapper;
import com.bytz.modules.cms.order.service.IOrderService;
import com.google.common.collect.Lists;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

/**
 * <p>
 * 莱宝CMS—订单管理-订单主表 服务实现类
 * </p>
 *
 * @author KyleWang
 * @since 2022-10-10
 */
@Service
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements IOrderService {

    @Override
    public List<Order> getOrderByStatus(String status) {
        return lambdaQuery().eq(Order::getStatus, status).list();
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean submitEcAuditFile(Order order) {
        return lambdaUpdate()
                .eq(Order::getId, order.getId())
                .in(Order::getEcStatus, Lists.newArrayList(OrderConstants.EcStatus.UNCOMMITTED, OrderConstants.EcStatus.REJECT))
                .set(Order::getEcAuditFile, order.getEcAuditFile())
                .set(Order::getEcAuditOtherFile, order.getEcAuditOtherFile())
                .set(Order::getEcStatus, OrderConstants.EcStatus.APPROVING)
                .update();
    }

    @Override
    public List<Order> getByReseller(String resellerId) {
        return lambdaQuery().eq(Order::getResellerId, resellerId).list();
    }

    @Override
    public List<Order> getByResellerAndStatus(String resellerId, Collection<String> status) {

        if (CollectionUtil.isEmpty(status)) {
            return new ArrayList<>();
        }

        return lambdaQuery()
                .eq(Order::getResellerId, resellerId)
                .in(Order::getStatus, status)
                .list();
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void submitPrepay(String orderId, BigDecimal prepayAmount) {
        lambdaUpdate()
                .set(Order::getPaidPrice, prepayAmount)
                .set(Order::getStatus, OrderConstants.OrderStatus.YI_YU_FU)
                .eq(Order::getId, orderId)
                .update();
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void submitBalancePay(Order order, BigDecimal payAmount, List<OrderItem> orderItems) {
        order.setPaidPrice(order.getPaidPrice().add(payAmount));
        boolean orderHasBeenDone = orderHasBeenDone(orderItems);

        lambdaUpdate()
                .set(Order::getPaidPrice, order.getPaidPrice())
                .set(orderHasBeenDone, Order::getStatus, OrderConstants.OrderStatus.YI_WAN_CHENG)
                .eq(Order::getId, order.getId())
                .update();
    }

    private boolean orderHasBeenDone(List<OrderItem> orderItems) {
        // 所有的都已发货则订单完成
        return orderItems.stream()
                .allMatch(p -> p.getShippedNum().compareTo(p.getProductNum()) == 0);
    }

    @Override
    public void updateArrivalStatus(String arrivalStatus, String contractNumber) {
        LambdaUpdateWrapper<Order> orderLambdaUpdateWrapper = new LambdaUpdateWrapper<>();
        orderLambdaUpdateWrapper.set(Order::getArrivalStatus, arrivalStatus)
                .eq(Order::getContractNumber, contractNumber);
        this.update(orderLambdaUpdateWrapper);
    }

    @Override
    public void updateArrivalStatusAndStatus(String orderId, String status, String arrivalStatus) {
        LambdaUpdateWrapper<Order> orderLambdaUpdateWrapper = new LambdaUpdateWrapper<>();
        orderLambdaUpdateWrapper.set(Order::getArrivalStatus, arrivalStatus)
                .set(Order::getStatus, status)
                .eq(Order::getId, orderId);
        this.update(orderLambdaUpdateWrapper);
    }

    @Override
    public List<Order> getOMReminderOrder() {
        return lambdaQuery()
                .in(Order::getStatus, Lists.newArrayList(
                        OrderConstants.OrderStatus.YI_YU_FU,
                        OrderConstants.OrderStatus.PAI_CHAN_ZHONG,
                        OrderConstants.OrderStatus.DAI_TI_JIAO_WEI_KUAN,
                        OrderConstants.OrderStatus.YI_WAN_CHENG))
                .isNull(Order::getReminderFlag)
                .list();
    }

    @Override
    public void setReminderFlagTrue(String id) {
        lambdaUpdate().eq(Order::getId, id).set(Order::getReminderFlag, true).update();
    }

    @Override
    public boolean saveEChopId(String orderId, Long documentId, String status) {
        return lambdaUpdate()
                .eq(Order::getId, orderId)
                .set(documentId != null, Order::getEChopDocumentId, documentId)
                .set(StringUtils.isNotBlank(status), Order::getStatus, status)
                .update();
    }

    @Override
    public List<Order> getPaymentOvertimeOrder() {
        return lambdaQuery()
                .le(Order::getPayExpireTime, LocalDateTime.now())
                .in(Order::getStatus, OrderConstants.OrderStatus.DAI_YU_FU, OrderConstants.OrderStatus.DAI_SHANG_CHUAN_HE_TONG)
//                .ne(Order::getStatus, OrderConstants.OrderStatus.YI_ZHONG_ZHI)
                .list();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateOrderExpired(String id) {
        lambdaUpdate()
                .eq(Order::getId, id)
                .set(Order::getStatus, OrderConstants.OrderStatus.YI_ZHONG_ZHI)
                .update();
    }
}
